package com.zdgk.core.mqtt;

import com.zdgk.core.control.config.MqttConfigInfo;
import com.zdgk.core.web.service.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;

import javax.annotation.Resource;

@Slf4j
public class MqttCallback implements MqttCallbackExtended {

    private MqttClientConfig mqttClientConfig;
    private ConfigService configService;

    public MqttCallback(MqttClientConfig mqttClientConfig, ConfigService configService) {
        this.mqttClientConfig = mqttClientConfig;
        this.configService = configService;
    }


    /**
     * 丢失连接，可在这里做重连
     * 只会调用一次
     *
     * @param throwable
     */
    @Override
    public void connectionLost(Throwable throwable) {
        log.error("mqtt 连接断开，5S之后尝试重连: {}", throwable.getMessage());
        long reconnectTimes = 1;
        while (true) {
            try {
                if (MqttClientConfig.getClient().isConnected()) {
                    //判断已经重新连接成功  需要重新订阅主题 可以在这个if里面订阅主题  或者 connectComplete（方法里面）  看你们自己选择
                    log.info("MQTT 重新连接  重新订阅成功");
                    return;
                }
                reconnectTimes+=1;
                log.warn("mqtt reconnect times = {} try again...  mqtt重新连接时间 {}", reconnectTimes, reconnectTimes);
                MqttClientConfig.getClient().reconnect();
            } catch (MqttException e) {
                log.error("mqtt断连异常", e);
            }
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e1) {
            }
        }
    }

    /**
     * @param topic
     * @param mqttMessage
     * @throws Exception
     * subscribe后得到的消息会执行到这里面
     */
    @Override
    public void messageArrived(String topic, MqttMessage mqttMessage){
        try {
            String msg = new String(mqttMessage.getPayload());
            log.info("原始接收内容>>>>>>接收消息主题 : {} 接收消息内容 : {}", topic, msg);
        }catch (Exception e){
            e.printStackTrace();
            log.error("接收到消息处理报错");
        }
    }


    /**
     *连接成功后的回调 可以在这个方法执行 订阅主题  生成Bean的 MqttConfiguration方法中订阅主题 出现bug
     *重新连接后  主题也需要再次订阅  将重新订阅主题放在连接成功后的回调 比较合理
     * @param reconnect
     * @param serverURI
     */
    @Override
    public  void  connectComplete(boolean reconnect,String serverURI){
        log.info("MQTT 连接成功，连接方式：{}",reconnect?"重连":"直连");
        MqttConfigInfo mqttKey = configService.getMqttKey();
        mqttClientConfig.subscribe(mqttKey.getMqttReceivedTopic(),0);
        log.info("MQTT 订阅成功");
    }


    /**
     * publish后，配送完成后回调的方法
     * @param iMqttDeliveryToken
     */
    @Override
    public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
//        log.info("==========deliveryComplete={}==========", iMqttDeliveryToken.isComplete());
    }
}

